/*
 * StructureHeaders.h
 *
 *  Created on: 13-Oct-2013
 *      Author: vikrantsingh
 */

#ifndef STRUCTUREHEADERS_H_

#define STRUCTUREHEADERS_H_

#include <vector>
#include <string>
#include "../dependency/GlobalStructures.h"
#include "GlobalVar.h"



#define PAGE_SIZE 4096
#define DIRECTORY_ENTRIES_COUNT ( PAGE_SIZE-sizeof(DirectoryPageHeader) ) / sizeof(DirectoryEntry)


#include<sstream>
using namespace std;

class RecordID {
    int pageNum;
    int slotNum;
};

class PageHeader {
public:
    int pageNumber;
    int nextPageNum;
    int pageType; // 0 - Directory Page
    // 1 - Data Page
    PageHeader();
    PageHeader(int pageNo, int nextPageNum, int pageType);
    string toString();
};



//class Page{
//	PageHeader pgHead;
//	char pageData[PAGE_SIZE]; 	// If Data Page:
//								// Last 4 bytes -> How many slots?
//
//
//};


///////////// DATA PAGE

class DataPageHeader {
public:
    PageHeader pgHeader;
    int noOfSlots;
    unsigned contFreeSpace;
    int cfsPtr; // pointer to the continous free space
    int dirHeaderPgNo;
    int dirPgNo; // for identifying DP chain
    int dirEntriesNo;
};

class SlotEntry {
public:
    int start;
    unsigned length;
    //int isFree; //1 -free,0-full

    std::string toString() {
        std::ostringstream mystream;
        mystream << "RECORD OFFSET: " << start << "\n";
        mystream << "RECORD LENGTH: " << length << "\n";
        return mystream.str();
    }
};

class contFreeSpace {
    int startOffset;
    int endOffset;
};

class SlotDirectory {
    contFreeSpace cfs;
    unsigned maxFree;
    int noOfSlots;
    //vector<Slot> slot;
};





/////////////  DIR PAGE

class DirectoryPageHeader {
public:
    PageHeader pgHeader;
    int nextDP; // Page number of next DP
    int deCount; // Count of DE in the current DP
    //int maxFreeSpace; 	// stores the max free Space in all DEs of DP
    // used to validate if the current Directory can allocate requested space
};

class DirectoryEntry {
public:
    int pageNumber;
    unsigned freeSpace;
    int entryNumber;

    std::string toString() {
        std::ostringstream mystream;
        mystream << "DIRECTORY ENTRY NUMBER: " << entryNumber << "\n";
        mystream << "PAGE NUMBER: " << pageNumber << "\n";
        mystream << "FREE SPACE:  " << freeSpace << "\n";
        return mystream.str();
    }
};

class DirectoryPage {
public:
    DirectoryPageHeader dirPageHeader;
    bool isPinned, isDirty;
    char *pageData;
    DirectoryPage();
    DirectoryPage(int pageNo);
    DirectoryPage(char *pageData);
    ~DirectoryPage();
    int getPageNo();
    STATUS_CODE createDP();
    void getDirEntry(int directoryEntryNumber, DirectoryEntry& dirEntry);
    int getNoOfDEs();
    void updateFreeSpace(int directoryEntryNumber, int freeSpace);
    void addDirEntry(int pageNumber, int freeSpace, DirectoryEntry& dirEntry);
    int getNextDP();
    void setNextDPNo(int pageNumber);
    string toString();


};


//class SlotUtil{
//
//	char[PAGE_SIZE] serializeDataPage(DataPage data){	// Saving In-Memory Page to Disk Page ( OO to String )
//           //
//
//	}
//
//
//	DataPage deserializeDataPage(char pageData[PAGE_SIZE]){	// Retriving In-Memory Page from Disk Page ( String to OO )
//
//	}
//
//
//	char[PAGE_SIZE] serializeDirPage(DirectoryPage data){	// Saving In-Memory Page to Disk Page ( OO to String )
//
//	}
//
//
//	DirectoryPage deserializeDirPage(char pageData[PAGE_SIZE]){	// Retriving In-Memory Page from Disk Page ( String to OO )
//
//	}
//};

typedef struct cahce_index {
    char _fileName[FILE_NAME_LENGTH];
    int _fd;
    int _open; // 0-close and 1- open 
}CACHE_INDEX;

    
#endif /* STRUCTUREHEADERS_H_ */
